package cc.wanforme.st.server.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;

@Configuration
@EnableCaching
public class RedisConfig {

	@Value("${spring.cache.redis.use-key-prefix:false}")
	private boolean userKeyPrefix;
	@Value("${spring.cache.redis.key-prefix:}")
	private String preffix;
	
	// 基于注解的缓存可以直接设置前缀，但手动操作 template 则需要手动设置
	
	@Bean
	public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
		
		//StringRedisSerializer stringSerializer = new StringRedisSerializer();
		PreffixStringRedisSerializer stringSerializer = new PreffixStringRedisSerializer(userKeyPrefix, preffix);
		GenericJackson2JsonRedisSerializer objSerializer = new GenericJackson2JsonRedisSerializer();
		
		// 新版时间序列化使用注解
		//@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
		//@JsonDeserialize(using = LocalDateTimeDeserializer.class)
		//@JsonSerialize(using = LocalDateTimeSerializer.class)
		
		redisTemplate.setKeySerializer(stringSerializer);
		redisTemplate.setValueSerializer(objSerializer);
		redisTemplate.setHashKeySerializer(stringSerializer);
		redisTemplate.setHashValueSerializer(objSerializer);
		redisTemplate.setConnectionFactory(lettuceConnectionFactory);
		
		return redisTemplate;
	}
	
	
	/** 带有特定前缀的 key 
	 * @author wanne
	 * @date 2022-03-31
	 */
	static class PreffixStringRedisSerializer extends StringRedisSerializer {
		
		private boolean userKeyPrefix;
		private String preffix;
		
		public PreffixStringRedisSerializer(boolean userKeyPrefix, String preffix) {
			super();
			this.userKeyPrefix = userKeyPrefix;
			this.preffix = preffix;
		}
		
		@Override
		public byte[] serialize(String key) {
			if(userKeyPrefix && StringUtils.hasText(preffix)) {
				key = preffix+key;
			}
			//System.out.println("<<<serialize>>>: " + key);
			return super.serialize(key);
		}
		@Override
		public String deserialize(byte[] bytes) {
			String key = super.deserialize(bytes);
			// 特定前缀开头的 key 去掉前缀
			if(userKeyPrefix && StringUtils.hasText(preffix) && key.startsWith(preffix)) {
				key = key.substring(preffix.length());
			}
			//System.out.println("<<<deserialize>>>: " + key);
			return key;
		}
	}
}
